package com.fy.proj3_deepseek_api.controller;

import com.fy.proj3_deepseek_api.service.DeepseekService;
import com.fy.proj3_deepseek_api.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/deepseek")
public class DeepseekController {

    @Autowired
    private DeepseekService deepseekService;

    // 请求参数类，用于接收JSON格式的请求体
    public static class GenerateRequest {
        private String prompt;
        private String model;
        private float temperature;
        private int max_tokens;
        
        // Getters and setters
        public String getPrompt() { return prompt; }
        public void setPrompt(String prompt) { this.prompt = prompt; }
        public String getModel() { return model; }
        public void setModel(String model) { this.model = model; }
        public float getTemperature() { return temperature; }
        public void setTemperature(float temperature) { this.temperature = temperature; }
        public int getMax_tokens() { return max_tokens; }
        public void setMax_tokens(int max_tokens) { this.max_tokens = max_tokens; }
    }
    
    // 文件上传请求参数类，用于支持文件上传和提示问题
    public static class FileUploadRequest {
        private String prompt; // 用户的问题或提示
        private String model; // 可选，指定使用的模型
        private float temperature; // 可选，指定温度参数
        private int max_tokens; // 可选，指定最大令牌数
        
        // Getters and setters
        public String getPrompt() { return prompt; }
        public void setPrompt(String prompt) { this.prompt = prompt; }
        public String getModel() { return model; }
        public void setModel(String model) { this.model = model; }
        public float getTemperature() { return temperature; }
        public void setTemperature(float temperature) { this.temperature = temperature; }
        public int getMax_tokens() { return max_tokens; }
        public void setMax_tokens(int max_tokens) { this.max_tokens = max_tokens; }
    }
    
    // 下载请求参数类，扩展GenerateRequest以支持接收已生成的回复内容
    public static class DownloadRequest extends GenerateRequest {
        private String response; // 可选字段，如果提供则直接使用该内容下载
        
        public String getResponse() { return response; }
        public void setResponse(String response) { this.response = response; }
    }

    /**
     * 调用DeepSeek API生成回复
     * @param request 包含提示内容等参数的请求体
     * @return 大模型生成的回复内容
     */
    @PostMapping("/generate")
    public ResponseEntity<Map<String, Object>> generateResponse(@RequestBody GenerateRequest request) {
        try {
            String response = deepseekService.generateResponse(
                request.getPrompt(), 
                request.getModel(), 
                request.getTemperature(), 
                request.getMax_tokens()
            );
            Map<String, Object> result = new HashMap<>();
            result.put("response", response);
            return ResponseEntity.ok(result);
        } catch (IOException e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("error", "API调用失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 上传多种文本文件作为提示内容，并获取大模型回复
     * 支持markdown、txt、json、csv、html等多种文本格式
     * @param file 上传的文本文件
     * @param request 包含提示问题和参数的请求
     * @return 大模型生成的回复内容
     */
    @PostMapping("/upload-file")
    public ResponseEntity<Map<String, Object>> uploadTextFile(
            @RequestParam("file") MultipartFile file,
            FileUploadRequest request) {
        try {
            // 设置最大文件大小为5MB
            long maxFileSize = 5 * 1024 * 1024;
            
            // 检查文件大小
            if (!FileUtil.isFileSizeAllowed(file, maxFileSize)) {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("error", "文件大小超过限制，最大允许5MB");
                return ResponseEntity.badRequest().body(errorResponse);
            }

            // 检查文件类型
            if (!FileUtil.isSupportedTextFile(file)) {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("error", "不支持的文件类型，请上传文本类文件（如txt、md、json、csv等）");
                return ResponseEntity.badRequest().body(errorResponse);
            }

            // 读取文件内容
            String fileContent = FileUtil.readTextFile(file);
            
            // 设置默认参数
            String model = request.getModel() != null ? request.getModel() : "deepseek-reasoner";
            float temperature = request.getTemperature() > 0 ? request.getTemperature() : 0.7f;
            int maxTokens = request.getMax_tokens() > 0 ? request.getMax_tokens() : 1024;
            
            // 如果没有提供提示问题，使用默认提示
            String prompt = request.getPrompt() != null ? request.getPrompt() : "请分析这个文件的内容并提供相关信息";
            
            // 调用API生成回复，支持文件内容分析
            String response = deepseekService.generateResponseWithFileContent(
                prompt, fileContent, model, temperature, maxTokens);
            
            Map<String, Object> result = new HashMap<>();
            result.put("response", response);
            result.put("file_extension", FileUtil.getFileExtension(file));
            result.put("file_size", file.getSize());
            
            return ResponseEntity.ok(result);
        } catch (IOException e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("error", "文件处理失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }
    
    /**
     * 上传Markdown文件作为提示内容，并获取大模型回复（向后兼容）
     * @param file 上传的Markdown文件
     * @return 大模型生成的回复内容
     */
    @PostMapping("/upload")
    public ResponseEntity<Map<String, Object>> uploadMarkdownFile(
            @RequestParam("file") MultipartFile file) {
        try {
            // 检查文件类型是否为markdown
            if (!FileUtil.isMarkdownFile(file)) {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("error", "请上传Markdown格式的文件(.md)");
                return ResponseEntity.badRequest().body(errorResponse);
            }

            // 读取文件内容作为提示
            String prompt = FileUtil.readTextFile(file);
            
            // 调用API生成回复，使用默认参数
            String response = deepseekService.generateResponseWithFileContent(prompt, null, "deepseek-reasoner", 0.7f, 1024);
            Map<String, Object> result = new HashMap<>();
            result.put("response", response);
            return ResponseEntity.ok(result);
        } catch (IOException e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("error", "文件处理失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 上传Markdown文件作为提示内容，并将大模型回复下载为Markdown文件
     * @param file 上传的Markdown文件
     * @return 包含大模型回复的Markdown文件下载
     */
    @PostMapping("/process-and-download")
    public ResponseEntity<ByteArrayResource> processAndDownloadMarkdown(
            @RequestParam("file") MultipartFile file) {
        try {
            // 检查文件类型
            if (!FileUtil.isMarkdownFile(file)) {
                Map<String, String> errorMap = new HashMap<>();
                errorMap.put("error", "请上传Markdown格式的文件(.md)");
                return ResponseEntity.badRequest()
                        .header("X-Error-Message", "请上传Markdown格式的文件(.md)")
                        .body(null);
            }

            // 读取文件内容作为提示
            String prompt = FileUtil.readTextFile(file);
            
            // 调用API生成回复，使用默认参数
            String response = deepseekService.generateResponseWithFileContent(prompt, null, "deepseek-reasoner", 0.7f, 1024);

            // 生成文件名（使用当前时间戳避免重名）
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String originalFilename = file.getOriginalFilename();
            String baseName = originalFilename != null ? originalFilename.replace(".md", "") : "response";
            String filename = baseName + "_response_" + timestamp + ".md";

            // 将回复内容转换为字节数组
            byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);
            ByteArrayResource resource = new ByteArrayResource(responseBytes);

            // 设置HTTP响应头，触发文件下载
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .contentLength(responseBytes.length)
                    .body(resource);
        } catch (IOException e) {
            return ResponseEntity.status(500).body(null);
        }
    }

    /**
     * 下载大模型回复为Markdown文件
     * @param request 包含提示内容或已生成回复的请求体
     * @return 包含大模型回复的Markdown文件下载
     */
    @PostMapping("/download-response")
    public ResponseEntity<ByteArrayResource> downloadResponseAsMarkdown(@RequestBody DownloadRequest request) {
        try {
            String responseContent;
            
            // 如果请求中包含已生成的回复内容，直接使用它
            if (request.getResponse() != null && !request.getResponse().trim().isEmpty()) {
                responseContent = request.getResponse();
            } else {
                // 否则调用API生成新的回复，使用请求中的参数
                responseContent = deepseekService.generateResponse(
                    request.getPrompt(), 
                    request.getModel(), 
                    request.getTemperature(), 
                    request.getMax_tokens()
                );
            }

            // 生成文件名
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String filename = "deepseek-response_" + timestamp + ".md";

            // 将回复内容转换为字节数组
            byte[] responseBytes = responseContent.getBytes(StandardCharsets.UTF_8);
            ByteArrayResource resource = new ByteArrayResource(responseBytes);

            // 设置HTTP响应头，触发文件下载
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .contentLength(responseBytes.length)
                    .body(resource);
        } catch (IOException e) {
            return ResponseEntity.status(500).body(null);
        }
    }
}